import sys
import wmi, zlib
import hashlib
import wmi
import zlib
import base64
import rsa
from rsa import common
import datetime


def base64encode(s:str):
    encoder = base64.b64encode(s.encode("utf-8"))
    str_encoder = encoder.decode('utf-8')
    return str_encoder 

def base64decode(str_encoder:str):
    decoder = base64.b64decode(str_encoder)
    s = decoder.decode('utf-8')
    return s 


class RSACipher:
    PUBLIC_KEY_PATH = 'rsa_public_key.pem'  # 公钥
    PRIVATE_KEY_PATH = 'rsa_private_key.pem'  # 私钥

    # 初始化key
    def __init__(self,
                 public_key_file=None,
                 private_key_file=None):

        if public_key_file:
            self.pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(open(public_key_file).read())
        if private_key_file:
            self.privkey = rsa.PrivateKey.load_pkcs1(open(private_key_file).read())

    @staticmethod
    def params_sort(params: dict) -> str:
        """
        参数 按照ASCII排序
        :param params: 参数dict
        :return: dict
        """
        params = sorted(params.items(), key=lambda item: item[0], reverse=False)
        return '&'.join([key + '=' + str(val) for key, val in params if key != 'sign'])

    def sign(self, params_str: str) -> str:
        """
        获取签名
        :param params: 加签数据
        :return: str
        """
#        params_str = RSACipher.params_sort(params)
        sign = rsa.sign(params_str.encode(), self.privkey, 'SHA-1')
        return base64.b64encode(sign).decode()

    def verify_sign(self, params_str: str,sign: str) -> bool:
        """
        签名验证
        :param pubkey: pubkey验证
        :param params: 验证数据
        :return: bool
        """
        try:
#            sign = params.get('sign')
#            params_str = RSACipher.params_sort(params)
            rsa.verify(params_str.encode(), base64.b64decode(sign), self.pubkey)
            return True
        except Exception as e:
            print(e)
            return False

    def encrypt(self, params: str) -> str:
        """
        数据公钥加密
        :param pubkey: pubkey加密
        :param params: 加密数据
        :return: data
        """
        encrypt_str = rsa.encrypt(params.encode(), self.pubkey)
        return base64.b64encode(encrypt_str).decode()

    def decrypt(self, sign: str):
        """
        数据私钥解密
        :param sign: 带解密字符串
        :return:
        """
        try:
            res = rsa.decrypt(base64.b64decode(sign), self.privkey)
            if isinstance(res, bytes):
                res = res.decode()
            return res
        except Exception as e:
            print(e)
            return None


def get_disk_info():
    tmplist = []
    encrypt_str = ""
    c = wmi.WMI()
    for cpu in c.Win32_Processor():
        # cpu 序列号
        encrypt_str = encrypt_str + cpu.ProcessorId.strip()
        # print("cpu id:", cpu.ProcessorId.strip())
 
    for physical_disk in c.Win32_DiskDrive():
        encrypt_str = encrypt_str + physical_disk.SerialNumber.strip()
 
        # # 硬盘序列号
        # print('disk id:', physical_disk.SerialNumber.strip())
 
        # tmpdict = {}
        # tmpdict["Caption"] = physical_disk.Caption
        # tmpdict["Size"] = int(physical_disk.Size) / 1000 / 1000 / 1000
        # tmplist.append(tmpdict)
    for board_id in c.Win32_BaseBoard():
        # 主板序列号
        encrypt_str = encrypt_str + board_id.SerialNumber.strip()
        # print("main board id:", board_id.SerialNumber.strip())
 
    #          for mac in c.Win32_NetworkAdapter():
 
    # mac 地址（包括虚拟机的）
    #                    print "mac addr:", mac.MACAddress:
    for bios_id in c.Win32_BIOS():
        # bios 序列号
        bios = bios_id.qualifiers["UUID"].strip()[1:-1].replace("-","")
        encrypt_str = encrypt_str + bios
        # print("bios number:", bios)
        # print("encrypt_str:", encrypt_str)
 
    # 加密算法
   # print(zlib.adler32(encrypt_str))
    return base64encode(encrypt_str)





##################################################################
# 命令行启动方式
# 在tools目录下执行

# server_licence.py 截至日期  客户机信息
# 例子
# server_licence.py 2020-01-23  pTpez6MSeq+sP+1sido9CuYUVCXPTHGcamI0RuVvMJas7kjxNY4svQcJbfX1ffMhCuQCjzgPfb2bYxiDlkjbUPL

# 生成  客户机信息.截至日期base64.签名
##################################################################

def main():
    if len(sys.argv) < 3:
        print("参数数量错误")
        return
    
    rsa = RSACipher(private_key_file=RSACipher.PRIVATE_KEY_PATH)

    expireDate = sys.argv[1]
    datetime.datetime.strptime(expireDate, "%Y-%m-%d")

    diskInfo = sys.argv[2]
    s12 = diskInfo+"."+base64encode(expireDate)
    s3 = rsa.sign(s12)

    s123 = s12+"."+s3

    print(s123)

if __name__ == "__main__":
    main()
